Skip to content

Narrow overload-error and symbol-use ranges to terminal identifier#19505

Open
Copilot wants to merge 1 commit into
mainfrom
copilot/fix-9141961-29048891-ac83c611-04a8-4bbc-9d1f-393ac1d7c4ba
Open

Narrow overload-error and symbol-use ranges to terminal identifier#19505
Copilot wants to merge 1 commit into
mainfrom
copilot/fix-9141961-29048891-ac83c611-04a8-4bbc-9d1f-393ac1d7c4ba

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 26, 2026

Fixes #14284, #3920

Problem

The FS0041 'No overloads match for method' error covered the entire expression including object access chains and arguments. For T.Instance.Method(""), the error underlined everything from T to ). This is especially problematic on larger expressions where the wide error range hides other diagnostics.

Similarly, FSharpSymbolUse ranges reported through the name-resolution sink (used by Find Usages, symbol highlight, and semantic classification) covered the whole dotted long-identifier span instead of just the terminal identifier.

Changes

NameResolution.fs/fsi

  • ComputeItemRange now returns (itemRange, itemIdentRange):
    • itemRange: structural whole-long-id span for typed-tree construction (unchanged behavior)
    • itemIdentRange: terminal identifier's own source range for diagnostics and sink reporting
  • ResolveLongIdentAsExprAndComputeRange and ResolveExprDotLongIdentAndComputeRange propagate itemIdentRange and use it for CallMethodGroupNameResolutionSink

CheckExpressions.fs

  • TcMethodApplication: intercepts UnresolvedOverloading errors and narrows the range from the whole expression to just the method name, with guards for multiline expressions, generic constructors, and backtick-escaped names

ServiceParamInfoLocations.fs

  • getAllCurriedArgsAtPosition: updated to handle narrowed symbol-use ranges by checking whether pos falls within the leaf function expression's range (excluding infix applications)

Tests

  • 7 new regression tests in OverloadResolutionErrorRangeTests.fs
  • Updated baselines across the test suite

Before

Error underlines T.Instance.Method("") — the entire expression.

After

Error underlines only Method — the method name.

Copilot AI requested a review from T-Gro March 26, 2026 22:17
@abonie
Copy link
Copy Markdown
Member

abonie commented Mar 31, 2026

@copilot Try again

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 31, 2026

@copilot Try again

Implemented the fix in commit aa4c1a9. The UnresolvedOverloading error range is now narrowed from the whole expression (mMethExpr) to just the method name identifier by computing the method-name-only range from mItem.End and methodName.Length in TcMethodApplication.

For T.Instance.Method(""), the error now covers only Method (Col 12-18) instead of the entire T.Instance.Method("") expression (Col 1-22). Added 4 regression tests covering instance calls, static calls, chained expressions, and lambda arguments. Tests and compiler build pass. Release notes and full test suite validation still pending.

Copilot AI changed the title [WIP] Copilot Request Narrow 'No matching overload' error range to method name only Mar 31, 2026
Copilot AI requested a review from abonie March 31, 2026 14:46
@T-Gro T-Gro force-pushed the copilot/fix-9141961-29048891-ac83c611-04a8-4bbc-9d1f-393ac1d7c4ba branch from aa4c1a9 to 7d2f1e9 Compare April 9, 2026 12:56
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 9, 2026

❗ Release notes required


✅ Found changes and release notes in following paths:

Change path Release notes path Description
src/Compiler docs/release-notes/.FSharp.Compiler.Service/11.0.100.md

Comment thread src/Compiler/Checking/Expressions/CheckExpressions.fs Outdated
@T-Gro T-Gro force-pushed the copilot/fix-9141961-29048891-ac83c611-04a8-4bbc-9d1f-393ac1d7c4ba branch 4 times, most recently from 2751d6e to 47b948d Compare April 16, 2026 07:44
@T-Gro T-Gro force-pushed the copilot/fix-9141961-29048891-ac83c611-04a8-4bbc-9d1f-393ac1d7c4ba branch 2 times, most recently from a5ac31e to fc504b7 Compare April 21, 2026 06:38
@T-Gro T-Gro marked this pull request as ready for review April 21, 2026 06:39
@T-Gro T-Gro requested a review from a team as a code owner April 21, 2026 06:39
@T-Gro T-Gro force-pushed the copilot/fix-9141961-29048891-ac83c611-04a8-4bbc-9d1f-393ac1d7c4ba branch from bfeba1a to e89bb2d Compare April 21, 2026 07:58
T-Gro added a commit that referenced this pull request Apr 21, 2026
Addresses reviewer feedback on PR #19505:
- r3058446895 / r3058471629: compute narrow ident range in name resolution
  so diagnostics and tooling (Find Usages, symbol highlight, FSharpSymbolUse)
  report on the item name rather than the full long-identifier path.

Approach: ComputeItemRange now returns (itemRange, itemIdentRange):
- itemRange (wide, unchanged) flows into typed-tree construction, sequence
  points, and the delay-rest continuation. Structural ranges and the debug
  experience are untouched.
- itemIdentRange (narrow, terminal ident) is consumed only by the
  CallMethodGroupNameResolutionSink / CallNameResolutionSink calls and
  RegisterUnionCaseTesterForProperty. This fixes #3920 at the source.

The PR #19505 post-hoc trim for FS0041 'No overloads match' is retained
because it narrows the overload-resolution diagnostic via column arithmetic
and is orthogonal to the sink narrowing.

FindReferences test expectations updated for 7 cases to reflect the
newly-correct narrow symbol-use ranges.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@T-Gro T-Gro force-pushed the copilot/fix-9141961-29048891-ac83c611-04a8-4bbc-9d1f-393ac1d7c4ba branch from 09db23f to 18ae276 Compare April 22, 2026 08:20
T-Gro added a commit that referenced this pull request Apr 22, 2026
Addresses reviewer feedback on PR #19505:
- r3058446895 / r3058471629: compute narrow ident range in name resolution
  so diagnostics and tooling (Find Usages, symbol highlight, FSharpSymbolUse)
  report on the item name rather than the full long-identifier path.

Approach: ComputeItemRange now returns (itemRange, itemIdentRange):
- itemRange (wide, unchanged) flows into typed-tree construction, sequence
  points, and the delay-rest continuation. Structural ranges and the debug
  experience are untouched.
- itemIdentRange (narrow, terminal ident) is consumed only by the
  CallMethodGroupNameResolutionSink / CallNameResolutionSink calls and
  RegisterUnionCaseTesterForProperty. This fixes #3920 at the source.

The PR #19505 post-hoc trim for FS0041 'No overloads match' is retained
because it narrows the overload-resolution diagnostic via column arithmetic
and is orthogonal to the sink narrowing.

FindReferences test expectations updated for 7 cases to reflect the
newly-correct narrow symbol-use ranges.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…14284, #3920)

Narrow the FS0041 'No overloads match' error range from the whole expression
to just the method name. For T.Instance.Method(""), the error now covers only
'Method' instead of 'T.Instance.Method("")'.

Also narrow name-resolution sink ranges (used by Find Usages, symbol highlight,
and semantic classification) to the terminal identifier of a dotted long
identifier instead of the whole object-expression path.

Changes:
- NameResolution.fs: ComputeItemRange now returns (itemRange, itemIdentRange).
  itemRange is the structural whole-long-id span for typed-tree construction.
  itemIdentRange is the terminal identifier's range for diagnostics and sinks.
- CheckExpressions.fs: Intercept UnresolvedOverloading errors in
  TcMethodApplication and narrow the error range to the method name.
- ServiceParamInfoLocations.fs: Update getAllCurriedArgsAtPosition to handle
  narrowed symbol-use ranges by also checking the leaf function expression.

Fixes #14284, #3920

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@T-Gro T-Gro changed the title Narrow 'No matching overload' error range to method name only Narrow overload-error and symbol-use ranges to terminal identifier Apr 22, 2026
@T-Gro T-Gro force-pushed the copilot/fix-9141961-29048891-ac83c611-04a8-4bbc-9d1f-393ac1d7c4ba branch from 5b96681 to 55769f8 Compare April 22, 2026 11:21

// mItem is the textual range covered by the long identifiers that make up the item
and TcItemThen (cenv: cenv) (overallTy: OverallTy) env tpenv (tinstEnclosing, item, mItem, rest, afterResolution) staticTyOpt delayed =
and TcItemThen (cenv: cenv) (overallTy: OverallTy) env tpenv (tinstEnclosing, item, mItem, _mItemIdent, rest, afterResolution) staticTyOpt delayed =
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the point of adding this parameter (_mItemIdent) that's only discarded?

@github-project-automation github-project-automation Bot moved this from New to In Progress in F# Compiler and Tooling Apr 30, 2026
T-Gro

This comment was marked as off-topic.

/// name. Fixes #14284 and #3920.
///
/// For `T.Instance.Method("")`:
/// itemRange = `T.Instance.Method`
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@T-Gro In what cases we'd want to use this range instead of the item one? It seems that when the whole range is required, we'd usually get it from the whole expression. Do some features rely on it?

@T-Gro T-Gro self-requested a review May 7, 2026 16:24
@T-Gro T-Gro added AI-reviewed PR reviewed by AI review council and removed AI-reviewed PR reviewed by AI review council labels May 7, 2026
Copy link
Copy Markdown
Member

@T-Gro T-Gro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review of PR #19505: Narrow overload-error and symbol-use ranges to terminal identifier

Summary

This PR addresses two longstanding issues:

  • #14284: FS0041 overload-resolution errors covering the entire expression (e.g., T.Instance.Method("")) instead of just the method name
  • #3920: FSharpSymbolUse ranges reported through the name-resolution sink covering the full dotted long-identifier span instead of the terminal identifier

The approach introduces a dual-range design in ComputeItemRange — separating the structural itemRange (for typed-tree construction) from the narrow itemIdentRange (for diagnostics and IDE symbol reporting). This is well-designed and addresses both issues cleanly.

Strengths

  1. Clean dual-range separation: ComputeItemRange returning (itemRange, itemIdentRange) is a principled design that keeps expression ranges intact for the typed tree while narrowing only the user-facing diagnostic/IDE surfaces.

  2. Defensive error-narrowing guards in TcMethodApplication: The three conditions — single-line check, methodName.Length < itemWidth, and DoesIdentifierNeedBackticks — correctly handle edge cases:

    • Multiline expressions where column arithmetic would be wrong
    • Generic constructors with internal names longer than source text (e.g., ImmutableStack1 vs ImmutableStack)
    • Backtick-escaped identifiers where methodName.Length doesn't account for delimiters
  3. Thorough test coverage: 7 new regression tests covering static, instance, chained, lambda, backtick, and multiline cases, plus extensive baseline updates across 35+ test files.

  4. ServiceParamInfoLocations.fs adaptation: The getLeafFuncExpr helper with the not isInfix guard correctly compensates for narrowed symbol-use positions without breaking infix operator resolution.

Observations / Discussion Points

  1. _mItemIdent in TcItemThen (line 8883): As @abonie noted, this parameter is passed through the 6-tuple but immediately discarded. It's carried because ResolveLongIdentAsExprAndComputeRange returns it and TcLongIdentThen passes the full result through, but TcItemThen itself doesn't need it — the narrowing happens either at the sink level (NameResolution.fs) or at the error level (TcMethodApplication). This is correct but adds structural noise. If there's no planned future use within TcItemThen, consider decomposing the result tuple before the call site (in TcLongIdentThen and TcTypeItemThen) to avoid propagating the unused field. Not a blocker.

  2. ComputeItemRange when rest <> []: When resolution consumes only a prefix (e.g., System.DateTime from System.DateTime.Now), itemIdentRange falls back to itemRange (the whole consumed prefix range). Ideally this could narrow to the last consumed identifier (e.g., just DateTime), but since the remaining identifiers are resolved separately via TcLookupThenResolveExprDotLongIdentAndComputeRange, this is benign — the terminal Now gets its own narrow range in the subsequent resolution call. The PR is conservative here and doesn't regress this case.

  3. getLeafFuncExpr performance: This recursive helper traverses the curried application spine on every VisitExpr callback. For deeply nested curried calls (e.g., f a b c d e), this is O(n) per visit. In practice this should be fine since application depth is bounded by typical code, but worth noting.

  4. @auduchinok's upstream question: The open discussion about whether mItem should be computed differently at an earlier stage (rather than trimming at TcMethodApplication) is a valid architectural concern. This PR takes a pragmatic approach: it does the principled narrowing at the ComputeItemRange level for symbol-use sinks (#3920), while applying a targeted error-range fix at TcMethodApplication for overload errors (#14284). Both are useful independently. The deeper refactoring of how mItem flows through the checker could be a follow-up.

Verdict

The changes are correct, well-guarded, and thoroughly tested. The dual-range design is a clean solution that avoids disrupting typed-tree expression ranges while improving diagnostic and IDE precision. The open review comments are non-blocking discussion points rather than correctness issues.

@T-Gro T-Gro added the AI-reviewed PR reviewed by AI review council label May 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI-reviewed PR reviewed by AI review council

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

'No matching overload' error has too wide range

4 participants